﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using SilverlightClient.SLWcfGeebaService;
using System.ServiceModel;
using SilverlightClient.Utils;
using System.Windows.Browser;
using System.Collections;
using SilverLightClient;

namespace SilverlightClient
{
    [ScriptableType]
    public partial class MainPage : UserControl
    {
        #region DataMembers

        private SLWcfGeebaService.SLServiceClient server;
        private User user;
        private string serverKey = EncDec.getServerKey();
        private RegistrationCW rgstrCW;


        #endregion

        public MainPage()
        {
            InitializeComponent();
            RegisterOnBeforeUnload();
            var address = new EndpointAddress("http://localhost:23620/SLService.svc");
            var binding = new PollingDuplexHttpBinding();
            this.server = new SLWcfGeebaService.SLServiceClient(binding,address);
            server.EditMessageReceived += new EventHandler<EditMessageReceivedEventArgs>(server_EditMessageReceived);
            server.UpdateReceived += new EventHandler<UpdateReceivedEventArgs>(server_UpdateReceived);
            server.slSubscribeCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(server_slSubscribeCompleted);
            this.rgstrCW = new RegistrationCW();

            this.RegisterServerEvents();
            this.server.entryAsync();
            
        }

        void server_UpdateReceived(object sender, UpdateReceivedEventArgs e)
        {
            //MessageBox.Show("New Message was published: id=" + e.message._id + ", content=" + e.message._content + ", modified date=" + e.message._modifiedDate + ", IsNotification=" + e.IsNotification);

                   
            SubfourmControl sfControl = (SubfourmControl)((ListBox)subforumsList).SelectedItem;
            GSubForum sf = new GSubForum();
            if (sfControl != null)
            {
                sf.topic = sfControl.txtTopic.Content.ToString();
                this.server.getThreadsAsync(sf, sf.topic);
            }

            if (e.IsNotification)
            {
                NotificationCW notifyWindow = new NotificationCW(e.message._id, e.message._content, DateTime.Now);//e.message._modifiedDate);
                notifyWindow.Show();
                notificationCenter.NotificationList.Items.Add(new Notification(e.message._id, e.message._content, DateTime.Now, e.IsNotification));//e.message._modifiedDate, e.IsNotification));
            }     
        }

        void server_EditMessageReceived(object sender, EditMessageReceivedEventArgs e)
        {
            //MessageBox.Show("UpdateReceived: id=" + e.message._id + ", content=" + e.message._content + ", modified date=" + e.message._modifiedDate);
            
            SubfourmControl currentSubForumControl = (SubfourmControl)((ListBox)subforumsList).SelectedItem;
            string currentSubForum = currentSubForumControl.txtTopic.Content.ToString();
            if (currentSubForum.Equals(e.subforumTopic.ToString()))
            {
                foreach (var thread in this.threadsTreeView.Items)
                {
                    ThreadControl threadControl = (ThreadControl)(((HeaderedItemsControl)(thread)).Header);
                    if (Int32.Parse(threadControl.tidTxt.Content.ToString()) == e.message._id)
                    {
                        //MessageBox.Show("Message is shown -> changing content");
                        threadControl.contentTxt.Text = e.message._content;
                        
                        LinearGradientBrush brush = new LinearGradientBrush();

                        GradientStop gradientStop1 = new GradientStop();
                        gradientStop1.Offset = 0;
                        gradientStop1.Color = Colors.Yellow;
                        brush.GradientStops.Add(gradientStop1);
            
                        GradientStop gradientStop2 = new GradientStop();
                        gradientStop2.Offset = 0.5;
                        gradientStop2.Color = Colors.White;
                        brush.GradientStops.Add(gradientStop2);

                        threadControl.label3.Background = brush;
                        threadControl.contentTxt.Background = brush;
                        //this.threadsTreeView.refresh()
                    }
                }
            }

            notificationCenter.NotificationList.Items.Add(new Notification(e.message._id, e.subforumTopic, e.message._content, e.message._modifiedDate));
            NotificationCW notifyWindow = new NotificationCW(e.message._id, e.subforumTopic, e.message._content, e.message._modifiedDate);
            notifyWindow.Show();

        }

        ~MainPage()
        {
            this.UnRegisterServerEvents();
        }

        #region OnBeforeUnload

        public void RegisterOnBeforeUnload()
        {
            //Register Silverlight object for availability in Javascript.
            const string scriptableObjectName = "Bridge";
            HtmlPage.RegisterScriptableObject(scriptableObjectName, this);
            //Start listening to Javascript event.
            string pluginName = HtmlPage.Plugin.Id;
            HtmlPage.Window.Eval(string.Format(
                @"window.onbeforeunload = function () {{
                    var control = document.getElementById('silverlightControl');
                    control.Content.Bridge.LogoutBeforeUnload();
                    return '';
                }}", pluginName, scriptableObjectName)
                );
        }

        [ScriptableMember]
        public void LogoutBeforeUnload()
        {
            if (this.user.userType != UserType.Guest)
            {
                server.logoutAsync(this.user.username);
            }
        }

        #endregion

        #region Events

        public void loginBtn_Click(object sender, RoutedEventArgs e)
        {
            if (loginBtn.Content.ToString().ToLower() == "login")
            {
                if ((usernameTxt.Text == "") || (passwordBox1.Password == ""))
                {
                    MessageBox.Show("Must enter Username and Password to login.");
                }
                else
                {
                    server.loginAsync(this.user, usernameTxt.Text,
                        EncDec.Encrypt(passwordBox1.Password, serverKey));
                    loginBtn.IsEnabled = false;
                }
            }
            else
            {
                server.logoutAsync(this.user.username);
                loginBtn.IsEnabled = false;
            }
        }
        private void signBtn_Click(object sender, RoutedEventArgs e)
        {
            this.rgstrCW.Show();

            signBtn.IsEnabled = false;
        }

        private void subforumsList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            GSubForum sf = null;
            SubfourmControl sfc = (SubfourmControl)((ListBox)sender).SelectedItem;
            if (sfc != null)
            {
                if ((this.user.userType != UserType.Admin) && (this.user.userType != UserType.Guest))
                {
                    if (sfc.isModerator(this.user.username))
                    {
                        privilagesLabel.Content = "Moderator";
                        tabModerator.IsEnabled = true;
                    }
                    else
                    {
                        privilagesLabel.Content = "Member";
                        tabModerator.IsEnabled = false;
                    }
                }
                sf = new GSubForum();
                sf.topic = (string)((SubfourmControl)((ListBox)sender).SelectedItem).txtTopic.Content;
                this.server.getThreadsAsync(sf, sf.topic);
            }

        }
        private void threadsTreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            int thId = -1;
            SubfourmControl sfControl = (SubfourmControl)((ListBox)subforumsList).SelectedItem;
            TreeViewItem tviControl = ((TreeViewItem)((TreeView)sender).SelectedItem);

            if (tviControl != null && sfControl != null)
            {
                thId = ((Int32)((ThreadControl)tviControl.Header).tidTxt.Content);
                this.server.getCommentsAsync(sfControl.txtTopic.Content.ToString(), thId, thId);
            }
        }

        private void addNewThreadBtn_Click(object sender, RoutedEventArgs e)
        {
            if (this.user.userType == UserType.Guest)
            {
                MessageBox.Show("Guest can not publish message.");
                return;
            }

            if ((subjectText.Text == "") && (contentText.Text == ""))
            {
                MessageBox.Show("A message must contain at least one of: Subject, Content.");
                return;
            }

            SubfourmControl sfControl = (SubfourmControl)((ListBox)subforumsList).SelectedItem;
            if (sfControl == null)
            {
                MessageBox.Show("No subforum selected to publish thread in.");
                return;
            }


            if (!(bool)cbIsPost.IsChecked)
            {
                addNewThreadBtn.IsEnabled = false;
                try
                {
                    GThread th = new GThread();
                    th._subject = subjectText.Text;
                    th._content = contentText.Text;
                    th._publisher = (Member)this.user;
                    th._publishDate = DateTime.Now;
                    server.publishAsync((Member)this.user, sfControl.txtTopic.Content.ToString(), th);
                }
                catch
                {
                    addNewThreadBtn.IsEnabled = true;
                }
            }
            else if (threadsTreeView.SelectedItem != null)
            {
                addNewThreadBtn.IsEnabled = false;

                try
                {
                    TreeViewItem tviControl = ((TreeViewItem)((TreeView)threadsTreeView).SelectedItem);
                    GPost post = new GPost();
                    post._subject = subjectText.Text;
                    post._content = contentText.Text;
                    post._publisher = (Member)this.user;
                    post._publishDate = DateTime.Now;

                    int thId = ((Int32)((ThreadControl)tviControl.Header).tidTxt.Content);

                    server.commentAsync((Member)this.user, post, sfControl.txtTopic.Content.ToString(), thId);
                }
                catch
                {
                    addNewThreadBtn.IsEnabled = true;
                }
            }
            else
            {
                MessageBox.Show("No thread selected to comment on.");
            }            
        }

        private void refreshSubforumsBtn_Click(object sender, RoutedEventArgs e)
        {
            if (this.user.userType != UserType.Admin)
            {
                privilagesLabel.Content = "Member";
            }
            server.getSubForumsAsync();

            refreshSubforumsBtn.IsEnabled = false;
        }
        private void btnSearch_Click(object sender, RoutedEventArgs e)
        {
            if (txtSearch.Text == "")
                return;

            if (cbSearchFilters.SelectedIndex == 0)
                server.searchByContentAsync(txtSearch.Text);
            else if (cbSearchFilters.SelectedIndex == 1)
                server.searchByUserAsync(txtSearch.Text);
        }

        private void editBtn_Click(object sender, RoutedEventArgs e)
        {
            SubfourmControl sfControl = (SubfourmControl)((ListBox)subforumsList).SelectedItem;
            TreeViewItem tviControl = ((TreeViewItem)((TreeView)threadsTreeView).SelectedItem);
            if (tviControl == null)
            {
                MessageBox.Show("No thread selected to edit.");
            }
            else
            {
                ThreadControl tc = (ThreadControl)tviControl.Header;
                if (tc.publishedByLabel.Content.ToString() != this.user.username)
                {
                    MessageBox.Show("You can only edit threads published by you.");
                    return;
                }
                if (editBtn.Content.ToString() == "Edit")
                {
                    tc.contentTxt.IsReadOnly = false;
                    bumpBtn.IsEnabled = false;
                    deleteBtn.IsEnabled = false;
                    addNewThreadBtn.IsEnabled = false;
                    tc.contentTxt.Focus();
                    editBtn.Content = "Save";
                }
                else
                {
                    editBtn.Content = "Edit";
                    server.editContentAsync((Member)this.user,
                        sfControl.txtTopic.Content.ToString(),
                        (int)((Int32)tc.tidTxt.Content),
                        tc.contentTxt.Text.ToString(),
                        tc);
                }
            }
        }
        private void bumpBtn_Click(object sender, RoutedEventArgs e)
        {
            SubfourmControl sfControl = (SubfourmControl)((ListBox)subforumsList).SelectedItem;
            TreeViewItem tviControl = ((TreeViewItem)((TreeView)threadsTreeView).SelectedItem);
            if (tviControl == null)
            {
                MessageBox.Show("No thread selected to bump.");
            }
            else
            {
                bumpBtn.IsEnabled = false;

                try
                {
                    GThread thread = ((ThreadControl)tviControl.Header).getThread();
                    int thId = ((Int32)((ThreadControl)tviControl.Header).tidTxt.Content);
                    server.bumpThreadAsync((Member)this.user, sfControl.txtTopic.Content.ToString(), thId, thread);
                }
                catch
                {
                    bumpBtn.IsEnabled = true;
                }
            }
        }
        private void deleteBtn_Click(object sender, RoutedEventArgs e)
        {
            deleteBtn.IsEnabled = false;

            try
            {
                SubfourmControl sfControl = (SubfourmControl)((ListBox)subforumsList).SelectedItem;
                TreeViewItem tviControl = ((TreeViewItem)((TreeView)threadsTreeView).SelectedItem);
                GThread thread = ((ThreadControl)tviControl.Header).getThread();
                int thId = ((Int32)((ThreadControl)tviControl.Header).tidTxt.Content);
                server.removeThreadAsync((Member)this.user, sfControl.txtTopic.Content.ToString(), thId);
            }
            catch
            {
                deleteBtn.IsEnabled = true;
            }
        }

        private void addSubfrmBtn_Click(object sender, RoutedEventArgs e)
        {
            if (tbSubforumTopic.Text != "")
            {
                addSubfrmBtn.IsEnabled = false;
                server.addSubForumAsync((Member)this.user, tbSubforumTopic.Text, this.user.username);
            }
        }
        private void removeSubforumsBtn_Click(object sender, RoutedEventArgs e)
        {
            SubfourmControl sfControl = (SubfourmControl)((ListBox)subforumsList).SelectedItem;
            if (sfControl != null)
            {
                removeSubforumsBtn.IsEnabled = false;
                server.removeSubForumAsync((Member)this.user, sfControl.txtTopic.Content.ToString());
            }
        }
        private void btnAddModerator_Click(object sender, RoutedEventArgs e)
        {
            SubfourmControl sfControl = (SubfourmControl)((ListBox)subforumsList).SelectedItem;
            if (sfControl != null && tbModeratorNameToAdd.Text != "")
            {
                btnAddModerator.IsEnabled = false;
                server.addModeratorAsync((Member)this.user, sfControl.txtTopic.Content.ToString(), tbModeratorNameToAdd.Text);
            }
        }
        private void tbRemoveModerator_Click(object sender, RoutedEventArgs e)
        {
            this.RemoveModerator();
        }
        private void tbSuspendModerator_Click(object sender, RoutedEventArgs e)
        {
            this.RemoveModerator();
        }
        private void btnReplaceModerator_Click(object sender, RoutedEventArgs e)
        {
            SubfourmControl sfControl = (SubfourmControl)((ListBox)subforumsList).SelectedItem;
            if (sfControl!= null && (tbModeratorNameToRemove.Text != "") && (tbModeratorNameToAdd.Text != ""))
            {
                btnReplaceModerator.IsEnabled = false;
                server.replaceModeratorAsync((Member)this.user, sfControl.txtTopic.Content.ToString(), tbModeratorNameToRemove.Text, tbModeratorNameToAdd.Text);
            }
        }
        private void btnReplaceAdmin_Click(object sender, RoutedEventArgs e)
        {
            if (tbReplaceAdmin.Text != "")
            {
                btnReplaceAdmin.IsEnabled = false;
                server.replaceAdminAsync((Member)this.user, tbReplaceAdmin.Text);
            }
        }
        private void btnChangePassword_Click(object sender, RoutedEventArgs e)
        {
            if (passwordBox3.Password != passwordBox4.Password)
            {
                MessageBox.Show("Passwords don't match!");
            }
            else
            {
                btnChangePassword.IsEnabled = false;
                server.changePasswordAsync((Member)this.user, EncDec.Encrypt(passwordBox2.Password, serverKey), EncDec.Encrypt(passwordBox3.Password, serverKey));
            }
        }
        private void btnEnableDisable_Click(object sender, RoutedEventArgs e)
        {
            if (btnEnableDisable.Content.ToString().ToLower().Equals("enable"))
            {
                server.SetActiveMemberAsync((Member)this.user, true);
            }
            else if (btnEnableDisable.Content.ToString().ToLower().Equals("disable"))
            {
                server.SetActiveMemberAsync((Member)this.user, false);
            }
            btnEnableDisable.IsEnabled = false;
        }
        private void btnBan_Click(object sender, RoutedEventArgs e)
        {
            bool canBan = this.user.userType == UserType.Admin;
            SubfourmControl sfc = (SubfourmControl)((ListBox)subforumsList).SelectedItem;
            if (sfc != null)
            {
                canBan |= sfc.isModerator(this.user.username);
            }

            if (!canBan)
            {
                return;
            }

            string username = txtUserNameBan.Text;

            if (username != null && username != "")
            {
                this.server.BanMemberAsync((Member)this.user, username, username);
            }
        }
        private void btnThreadCountForUser_Click(object sender, RoutedEventArgs e)
        {
            if (this.user != null && this.user.userType == UserType.Admin && txtThreadCountForUser.Text != "")
            {
                this.server.getMemberThreadCountAsync((Member)this.user, txtThreadCountForUser.Text);

            }
        }

        // Registration Child Window
        void rgstrCW_Closed(object sender, EventArgs e)
        {
            if (((RegistrationCW)sender).DialogResult.Value)
            {
                string username = ((RegistrationCW)sender).tbUsername.Text;
                string password = ((RegistrationCW)sender).pbPassword.Password;

                // For Automatic login after registration
                this.usernameTxt.Text = username;
                this.passwordBox1.Password = password;

                server.registerAsync(username, EncDec.Encrypt(password, serverKey));
            }
            else
            {
                signBtn.IsEnabled = true;
            }
        }

        #endregion

        #region Results

        void server_entryCompleted(object sender, entryCompletedEventArgs e)
        {
            this.user = e.Result;
            if (this.user != null)
            {
                userNameLabel.Content = this.user.username;
                privilagesLabel.Content = "Guest";
                
                //interactive:
                server.slSubscribeAsync(this.user.username);

                this.server.getSubForumsAsync();
            }
        }

        //can remove this method: maybe show some kind of error message if failed to subscribe for interactive
        void server_slSubscribeCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                MessageBox.Show("Error Registering Interactive push notifications on server: " + e.Error);
            }
        }

        void server_logoutCompleted(object sender, logoutCompletedEventArgs e)
        {
            this.user = e.Result;

            if (e.Result != null)
            {
                userNameLabel.Content = this.user.username;
                privilagesLabel.Content = "Guest";

                signBtn.IsEnabled = true;
                this.EnableDisableTabs(false);
                tabOptions.SelectedIndex = 0;
                loginBtn.Content = "login";
                server.getSubForumsAsync();
            }
            loginBtn.IsEnabled = true;
        }
        void server_registerCompleted(object sender, registerCompletedEventArgs e)
        {
            if (!e.Result)
            {
                MessageBox.Show("Failed to register.");
            }
            else
            {
                server.loginAsync(this.user, usernameTxt.Text, EncDec.Encrypt(passwordBox1.Password, serverKey));
            }
            signBtn.IsEnabled = true;
        }
        void server_loginCompleted(object sender, loginCompletedEventArgs e)
        {
            if (e.Result == null || e.Result.username == null)
            {
                MessageBox.Show("Failed to login");
                loginBtn.IsEnabled = true;
                return;
            }

            this.user = e.Result;

            userNameLabel.Content = this.user.username;
            privilagesLabel.Content = "Member";
            if (this.user.userType == UserType.Admin)
            {
                privilagesLabel.Content = "Admin";
            }

            this.clearUserAndPass();
            signBtn.IsEnabled = false;
            this.EnableDisableTabs(true);

            loginBtn.Content = "logout";

            if (((Member)this.user).isActive)
            {
                btnEnableDisable.Content = "Disable";
            }
            else
            {
                btnEnableDisable.Content = "Enable";
            }
            server.getSubForumsAsync();

            //interactive:
            server.slSubscribeAsync(this.user.username);

            loginBtn.IsEnabled = true;
        }
        void server_getSubForumsCompleted(object sender, getSubForumsCompletedEventArgs e)
        {
            this.ShowSubforums(e.Result.ToList<GSubForum>());
        }
        void server_getThreadCountCompleted(object sender, getThreadCountCompletedEventArgs e)
        {
            SubfourmControl sfControl = null; ;
            foreach (SubfourmControl sfc in subforumsList.Items)
            {
                if (sfc.txtTopic.Content.ToString().Equals(e.UserState.ToString()))
                {
                    sfControl = sfc;
                    break;
                }
            }
            if (e.Result < 0 || e.UserState == null)
            {
                //server.getThreadCountAsync((Member)this.user, sfControl.txtTopic.Content.ToString(), sfControl.txtTopic.Content);
                return;
            }
            sfControl.labelThreadCount.Visibility = System.Windows.Visibility.Visible;
            sfControl.txtThreadCount.Visibility = System.Windows.Visibility.Visible;
            sfControl.txtThreadCount.Content = e.Result.ToString();
        }
        void server_getModeratorsCompleted(object sender, getModeratorsCompletedEventArgs e)
        {
            SubfourmControl sfControl = null; ;
            foreach (SubfourmControl sfc in subforumsList.Items)
            {
                if (sfc.txtTopic.Content.ToString().Equals(e.UserState.ToString()))
                {
                    sfControl = sfc;
                    break;
                }
            }
            if (e.Result.Count == 0 || e.UserState == null)
            {
                server.getModeratorsAsync((Member)this.user, sfControl.txtTopic.Content.ToString(), sfControl.txtTopic.Content);
                return;
            }
            string tooltip = "";
            foreach (Member m in e.Result)
            {
                sfControl.addModerator(m.username);
                tooltip += m.username + ", ";
            }
            ToolTipService.SetToolTip(sfControl.img, tooltip.Substring(0, tooltip.Length - 2));
        }

        void server_getThreadsCompleted(object sender, getThreadsCompletedEventArgs e)
        {
            SubfourmControl sfControl = (SubfourmControl)((ListBox)subforumsList).SelectedItem;
            if (this.user.userType == UserType.Admin)
            {
                server.getThreadCountAsync((Member)this.user, sfControl.txtTopic.Content.ToString(), sfControl.txtTopic.Content);
            }
            if (e.UserState != null && e.Result != null)
            {
                this.ShowThreads(e.UserState.ToString(), e.Result.ToList<GThread>());
            }
        }
        void server_getCommentsCompleted(object sender, getCommentsCompletedEventArgs e)
        {
            if (e.UserState != null && e.Result != null)
            {
                List<GPost> posts = e.Result.ToList<GPost>();
                posts = posts.OrderByDescending(post => post._modifiedDate).ToList<GPost>();
                TreeViewItem tviControl = ((TreeViewItem)((TreeView)threadsTreeView).SelectedItem);

                tviControl.Items.Clear();

                foreach (GPost post in posts)
                {
                    if (((Int32)((ThreadControl)tviControl.Header).tidTxt.Content) == (Int32)e.UserState)
                    {
                        TreeViewItem tvi = new TreeViewItem();
                        tvi.Header = new ThreadControl(this.user, post);//, e.UserState.ToString());
                        tviControl.Items.Add(tvi);
                    }
                }

                tviControl.IsExpanded = true;
            }
        }
        void server_publishCompleted(object sender, publishCompletedEventArgs e)
        {
            if (e.Result > 0)
            {
                GSubForum sf = null;

                if (((SubfourmControl)((ListBox)subforumsList).SelectedItem) != null)
                {
                    sf = new GSubForum();
                    sf.topic = (string)((SubfourmControl)((ListBox)subforumsList).SelectedItem).txtTopic.Content;
                    this.server.getThreadsAsync(sf, sf.topic);
                }

                server.getMemberThreadCountAsync((Member)this.user, this.user.username);
                this.clearAddThread();
                //MessageBox.Show("Thread posted.");
            }

            addNewThreadBtn.IsEnabled = true;
        }
        void server_commentCompleted(object sender, commentCompletedEventArgs e)
        {
            if (e.Result > 0)
            {
                GSubForum sf = null;

                if (((SubfourmControl)((ListBox)subforumsList).SelectedItem) != null)
                {
                    sf = new GSubForum();
                    sf.topic = (string)((SubfourmControl)((ListBox)subforumsList).SelectedItem).txtTopic.Content;
                    this.server.getThreadsAsync(sf, sf.topic);
                }

                server.getMemberThreadCountAsync((Member)this.user, this.user.username);
                this.clearAddThread();
                //MessageBox.Show("Comment posted.");
            }

            addNewThreadBtn.IsEnabled = true;
        }
        
        void server_editContentCompleted(object sender, editContentCompletedEventArgs e)
        {
            if (e.Result)
            {
                ThreadControl tc = (ThreadControl)e.UserState;
                tc.contentTxt.IsReadOnly = true;
            }

            bumpBtn.IsEnabled = true;
            deleteBtn.IsEnabled = true;
            addNewThreadBtn.IsEnabled = true;
        }
        void server_bumpThreadCompleted(object sender, bumpThreadCompletedEventArgs e)
        {
            if (e.Result)
            {
                SubfourmControl sfControl = (SubfourmControl)((ListBox)subforumsList).SelectedItem;
                GSubForum sf = new GSubForum();
                sf.topic = sfControl.txtTopic.Content.ToString();
                this.server.getThreadsAsync(sf, sf.topic);
            }

            bumpBtn.IsEnabled = true;
        }
        void server_removeThreadCompleted(object sender, removeThreadCompletedEventArgs e)
        {
            if (e.Result)
            {
                GSubForum sf = null;

                if (((SubfourmControl)((ListBox)subforumsList).SelectedItem) != null)
                {
                    sf = new GSubForum();
                    sf.topic = (string)((SubfourmControl)((ListBox)subforumsList).SelectedItem).txtTopic.Content;
                    this.server.getThreadsAsync(sf, sf.topic);
                }

                this.clearAddThread();
                //MessageBox.Show("Message removed.");
            }
            else
            {
                MessageBox.Show("Can't remove message.");
            }

            deleteBtn.IsEnabled = true;
        }

        void server_addSubForumCompleted(object sender, addSubForumCompletedEventArgs e)
        {
            if (e.Result)
            {
                MessageBox.Show("Subforum added.");
                this.clearAdminSection();
            }
            else
            {
                MessageBox.Show("Failed to add Subforum.");
                addSubfrmBtn.IsEnabled = true;
                return;
            }

            server.getSubForumsAsync();

            addSubfrmBtn.IsEnabled = true;
        }
        void server_removeSubForumCompleted(object sender, removeSubForumCompletedEventArgs e)
        {
            if (e.Result)
            {
                MessageBox.Show("Subforum removed.");
            }
            else
            {
                MessageBox.Show("Failed to remove Subforum.");
                removeSubforumsBtn.IsEnabled = true;
                return;
            }

            server.getSubForumsAsync();

            removeSubforumsBtn.IsEnabled = true;
        }
        void server_addModeratorCompleted(object sender, addModeratorCompletedEventArgs e)
        {
            if (e.Result)
            {
                MessageBox.Show("Moderator added.");
                this.clearAdminSection();
            }
            else
            {
                MessageBox.Show("Failed to add Moderator.");
                btnAddModerator.IsEnabled = true;
                return;
            }

            server.getSubForumsAsync();

            btnAddModerator.IsEnabled = true;
        }
        void server_removeModeratorCompleted(object sender, removeModeratorCompletedEventArgs e)
        {
            if (e.Result)
            {
                MessageBox.Show("Moderator removed/Suspended.");
                this.clearAdminSection();
            }
            else
            {
                MessageBox.Show("Failed to remove/suspend Moderator.");
                tbRemoveModerator.IsEnabled = true;
                tbSuspendModerator.IsEnabled = true;
                return;
            }

            server.getSubForumsAsync();

            tbRemoveModerator.IsEnabled = true;
            tbSuspendModerator.IsEnabled = true;
        }
        void server_replaceModeratorCompleted(object sender, replaceModeratorCompletedEventArgs e)
        {
            if (e.Result)
            {
                MessageBox.Show("Moderator replaced.");
                this.clearAdminSection();
            }
            else
            {
                MessageBox.Show("Failed to replace Moderator.");
                btnReplaceModerator.IsEnabled = true;
                return;
            }

            server.getSubForumsAsync();

            btnReplaceModerator.IsEnabled = true;
        }
        void server_replaceAdminCompleted(object sender, replaceAdminCompletedEventArgs e)
        {
            if (e.Result)
            {
                MessageBox.Show("Admin replaced.");
                this.clearAdminSection();
            }
            else
            {
                MessageBox.Show("Failed to replace Admin.");
                btnReplaceAdmin.IsEnabled = true;
                return;
            }

            server.logoutAsync(this.user.username);

            btnReplaceAdmin.IsEnabled = true;
        }
        void server_getMemberThreadCountCompleted(object sender, getMemberThreadCountCompletedEventArgs e)
        {
            if (e.Result != -1)
            {
                MessageBox.Show(txtThreadCountForUser.Text + " published " + e.Result + " threads");
                txtThreadCountForUser.Text = "";
            }

            txtThreadCountForUser.Text = "";
        }
        void server_getConnectedMembersCountCompleted(object sender, getConnectedMembersCountCompletedEventArgs e)
        {
            loggedInLabel.Content = e.Result;
        }
        void server_changePasswordCompleted(object sender, changePasswordCompletedEventArgs e)
        {
            if (e.Result)
            {
                MessageBox.Show("Password changed successfully");
                ClearPasswordSection();
            }
            else
            {
                MessageBox.Show("Change password failed!");
            }

            btnChangePassword.IsEnabled = true;
        }
        void server_SetActiveMemberCompleted(object sender, SetActiveMemberCompletedEventArgs e)
        {
            if (e.Result)
            {
                MessageBox.Show("Member is " + btnEnableDisable.Content + "d");
                ((Member)this.user).isActive = !((Member)this.user).isActive;
                if (btnEnableDisable.Content.ToString().ToLower().Equals("enable"))
                {
                    btnEnableDisable.Content = "Disable";
                }
                else if (btnEnableDisable.Content.ToString().ToLower().Equals("disable"))
                {
                    btnEnableDisable.Content = "Enable";
                }
            }
            else
            {
                MessageBox.Show("Failed to " + btnEnableDisable.Content.ToString());
            }
            btnEnableDisable.IsEnabled = true;
        }
        void server_BanMemberCompleted(object sender, BanMemberCompletedEventArgs e)
        {
            if (e.Result == true)
            {
                MessageBox.Show("Member " + e.UserState.ToString() + " is banned");
            }
            else
            {
                MessageBox.Show("Failed to ban Member " + e.UserState.ToString());
            }
            txtUserNameBan.Text = "";
        }

        void server_searchByUserCompleted(object sender, searchByUserCompletedEventArgs e)
        {
            this.ShowThreads("search", e.Result.ToList());
        }
        void server_searchByContentCompleted(object sender, searchByContentCompletedEventArgs e)
        {
            this.ShowThreads("search", e.Result.ToList());
        }

        #endregion

        #region help methods

        private void RegisterServerEvents()
        {
            server.entryCompleted += new EventHandler<entryCompletedEventArgs>(server_entryCompleted);
            server.registerCompleted += new EventHandler<registerCompletedEventArgs>(server_registerCompleted);
            server.loginCompleted += new EventHandler<loginCompletedEventArgs>(server_loginCompleted);
            server.logoutCompleted += new EventHandler<logoutCompletedEventArgs>(server_logoutCompleted);
            server.getSubForumsCompleted += new EventHandler<getSubForumsCompletedEventArgs>(server_getSubForumsCompleted);
            server.getThreadCountCompleted += new EventHandler<getThreadCountCompletedEventArgs>(server_getThreadCountCompleted);
            server.getModeratorsCompleted += new EventHandler<getModeratorsCompletedEventArgs>(server_getModeratorsCompleted);
            server.getThreadsCompleted += new EventHandler<getThreadsCompletedEventArgs>(server_getThreadsCompleted);
            server.getCommentsCompleted += new EventHandler<getCommentsCompletedEventArgs>(server_getCommentsCompleted);
            server.publishCompleted += new EventHandler<publishCompletedEventArgs>(server_publishCompleted);
            server.commentCompleted += new EventHandler<commentCompletedEventArgs>(server_commentCompleted);

            server.editContentCompleted += new EventHandler<editContentCompletedEventArgs>(server_editContentCompleted);
            server.bumpThreadCompleted += new EventHandler<bumpThreadCompletedEventArgs>(server_bumpThreadCompleted);

            server.addSubForumCompleted += new EventHandler<addSubForumCompletedEventArgs>(server_addSubForumCompleted);
            server.removeSubForumCompleted += new EventHandler<removeSubForumCompletedEventArgs>(server_removeSubForumCompleted);
            server.addModeratorCompleted += new EventHandler<addModeratorCompletedEventArgs>(server_addModeratorCompleted);
            server.removeModeratorCompleted += new EventHandler<removeModeratorCompletedEventArgs>(server_removeModeratorCompleted);
            server.replaceModeratorCompleted += new EventHandler<replaceModeratorCompletedEventArgs>(server_replaceModeratorCompleted);
            server.replaceAdminCompleted += new EventHandler<replaceAdminCompletedEventArgs>(server_replaceAdminCompleted);
            server.removeThreadCompleted += new EventHandler<removeThreadCompletedEventArgs>(server_removeThreadCompleted);
            server.getMemberThreadCountCompleted += new EventHandler<getMemberThreadCountCompletedEventArgs>(server_getMemberThreadCountCompleted);
            server.getConnectedMembersCountCompleted += new EventHandler<getConnectedMembersCountCompletedEventArgs>(server_getConnectedMembersCountCompleted);
            server.changePasswordCompleted += new EventHandler<changePasswordCompletedEventArgs>(server_changePasswordCompleted);
            server.SetActiveMemberCompleted += new EventHandler<SetActiveMemberCompletedEventArgs>(server_SetActiveMemberCompleted);
            server.BanMemberCompleted += new EventHandler<BanMemberCompletedEventArgs>(server_BanMemberCompleted);

            // Registration Child Window
            this.rgstrCW.Closed += new EventHandler(rgstrCW_Closed);

            // search
            server.searchByContentCompleted += new EventHandler<searchByContentCompletedEventArgs>(server_searchByContentCompleted);
            server.searchByUserCompleted += new EventHandler<searchByUserCompletedEventArgs>(server_searchByUserCompleted);
        }

        private void UnRegisterServerEvents()
        {
            server.entryCompleted -= server_entryCompleted;
            server.registerCompleted -= server_registerCompleted;
            server.loginCompleted -= server_loginCompleted;
            server.logoutCompleted -= server_logoutCompleted;
            server.getSubForumsCompleted -= server_getSubForumsCompleted;
            server.getThreadCountCompleted -= server_getThreadCountCompleted;
            server.getModeratorsCompleted -= server_getModeratorsCompleted;
            server.getThreadsCompleted -= server_getThreadsCompleted;
            server.getCommentsCompleted -= server_getCommentsCompleted;
            server.publishCompleted -= server_publishCompleted;
            server.commentCompleted -= server_commentCompleted;

            server.editContentCompleted -= server_editContentCompleted;
            server.bumpThreadCompleted -= server_bumpThreadCompleted;

            server.addSubForumCompleted -= server_addSubForumCompleted;
            server.removeSubForumCompleted -= server_removeSubForumCompleted;
            server.addModeratorCompleted -= server_addModeratorCompleted;
            server.removeModeratorCompleted -= server_removeModeratorCompleted;
            server.replaceModeratorCompleted -= server_replaceModeratorCompleted;
            server.replaceAdminCompleted -= server_replaceAdminCompleted;
            server.removeThreadCompleted -= server_removeThreadCompleted;
            server.getMemberThreadCountCompleted -= server_getMemberThreadCountCompleted;
            server.getConnectedMembersCountCompleted -= server_getConnectedMembersCountCompleted;
            server.changePasswordCompleted -= server_changePasswordCompleted;
            server.SetActiveMemberCompleted -= server_SetActiveMemberCompleted;

            //search
            server.searchByContentCompleted -= server_searchByContentCompleted;
            server.searchByUserCompleted -= server_searchByUserCompleted;
        }
        
        private void clearUserAndPass()
        {
            usernameTxt.Text = "";
            passwordBox1.Password = "";
        }
        private void clearAddThread()
        {
            subjectText.Text = "";
            contentText.Text = "";
        }
        private void clearAdminSection()
        {
            tbSubforumTopic.Text = "";
            tbModeratorNameToAdd.Text = "";
            tbModeratorNameToRemove.Text = "";
            tbReplaceAdmin.Text = "";
        }
        private void ClearPasswordSection()
        {
            passwordBox2.Password = "";
            passwordBox3.Password = "";
            passwordBox4.Password = "";
        }
        private void ShowThreads(string topic, List<GThread> threads)
        {
            threadsTreeView.Items.Clear();
            if (topic != null && threads != null)
            {
                threads = threads.OrderByDescending(thread => thread._modifiedDate).ToList<GThread>();
                foreach (GThread thread in threads)
                {
                    TreeViewItem tvi = new TreeViewItem();
                    tvi.Header = new ThreadControl(this.user, thread);//, topic);
                    threadsTreeView.Items.Add(tvi);
                }
            }
            server.getConnectedMembersCountAsync();
        }
        private void ShowSubforums(List<GSubForum> subforums)
        {
            this.subforumsList.Items.Clear();
            this.threadsTreeView.Items.Clear();

            try
            {
                foreach (GSubForum sf in subforums)
                {
                    if (this.user.userType != UserType.Guest)
                    {
                        server.getThreadCountAsync((Member)this.user, sf.topic, sf.topic);
                        server.getModeratorsAsync((Member)this.user, sf.topic, sf.topic);
                    }
                    subforumsList.Items.Add(new SubfourmControl(sf.topic, ""));
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("loadSubforumsFromServer Error! " + ex.Message);
            }
            server.getConnectedMembersCountAsync();

            refreshSubforumsBtn.IsEnabled = true;
        }
        private void EnableDisableTabs(bool eneable)
        {
            tabThread.IsEnabled = eneable;
            tabChangePw.IsEnabled = eneable;
            tabAdmin.IsEnabled = false;
            tabModerator.IsEnabled = false;

            if (this.user.userType == UserType.Admin)
            {
                tabAdmin.IsEnabled = true;
                tabModerator.IsEnabled = true;
            }
        }
        private void RemoveModerator()
        {
            SubfourmControl sfControl = (SubfourmControl)((ListBox)subforumsList).SelectedItem;
            if (sfControl != null && tbModeratorNameToRemove.Text != "")
            {
                tbRemoveModerator.IsEnabled = false;
                tbSuspendModerator.IsEnabled = false;
                server.removeModeratorAsync((Member)this.user, sfControl.txtTopic.Content.ToString(), tbModeratorNameToRemove.Text);
            }
        }
        #endregion

        #region flipPanel
        private void Button_ShowNotifications_Click(object sender, RoutedEventArgs e)
        {
            Flipper.Page2Visible = true;
        }

        private void Button_ShowThreads_Click(object sender, RoutedEventArgs e)
        {
            Flipper.Page2Visible = false;
        }
        #endregion

        public SLWcfGeebaService.SLServiceClient getServer()
        {
            return server;
        }
    }
}
